package com.lwl.concurrency.collection;

import java.util.concurrent.PriorityBlockingQueue;

/**
 * <pre>
 *  PriorityBlockingQueue使用compareTo()方法决定插入元素的位置。（校注：默认情况下）较大的元素将被放在队列的尾部
 *  compareTo()方法将返回0。在这种情况下，PriorityBlockingQueue类并不能保证元素的顺序。
 *  clear()：这个方法删除队列中的所有元素。
 *  take()：这个方法返回并删除队列中的第一个元素。如果队列是空的，这个方法将阻塞线程直到队列有元素。
 *  put(E e)：E是用来参数化PriorityBlockingQueue类的类。这个方法将作为参数传入的元素插入到队列中。
 *  peek()：这个方法返回列队的第一个元素，但不删除它。
 *  基于优先级的线程安全阻塞队列
 * </pre>
 *
 * Created by liwenlong on 2018/1/16 14:26
 */
public class PriorityBlockingQueueTest {

    public static class Event implements Comparable<Event> {
        private int thread; //
        // 记录已创建事件的线程数
        private int priority;

        public int getPriority() {
            return priority;
        }

        public int getThread() {
            return thread;
        }

        public Event(int thread, int priority) {
            this.thread = thread;
            this.priority = priority;
        }

        @Override
        public int compareTo(Event event) {
            return event.getPriority() - this.priority;
            //System.out.println("....."+(this.priority - event.getPriority()));
            /*if (this.priority > event.getPriority()) {
                return -1;
            } else if (this.priority < event.getPriority()) {
                return 1;
            }
            return 0;*/
        }
    }

    public static class Task implements Runnable {
        private int id;
        private PriorityBlockingQueue<Event> queue;

        public Task(int id, PriorityBlockingQueue<Event> queue) {
            this.id = id;
            this.queue = queue;
        }

        @Override
        public void run() {
            for (int i = 0; i < 1000; i++) {
                Event event = new Event(id, i);
                queue.add(event);
            }
        }
    }

    public static void main(String[] args) {
        /*PriorityBlockingQueue<Event> queue = new PriorityBlockingQueue<>();
        Thread[] taskThreads = new Thread[5];
        //创建线程数组和任务
        for (int i = 0; i < taskThreads.length; i++) {
            Task task = new Task(i, queue);
            taskThreads[i] = new Thread(task);
        }
        //执行线程
        for (int i = 0; i < taskThreads.length; i++) {
            taskThreads[i].start();
        }
        //线程等待
        for (int i = 0; i < taskThreads.length; i++) {
            try {
                taskThreads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf("Main: Queue Size: %d\n", queue.size());
        for (int i = 0; i < taskThreads.length * 1000; i++) {
            Event event = queue.poll();
            System.out.printf("Thread %s: Priority %d\n", event.getThread(), event.getPriority());
        }
        System.out.printf("Main: Queue Size: %d\n", queue.size());
        System.out.printf("Main: End of the program\n");*/

        PriorityBlockingQueue<Event> blockingQueue = new PriorityBlockingQueue<>(3);

        blockingQueue.add(new Event(1,1));
        blockingQueue.add(new Event(1,3));
        blockingQueue.add(new Event(1,2));
        System.out.println("add..................................");
        blockingQueue.add(new Event(1,9));
        blockingQueue.add(new Event(1,8));

        /*for (int i = 0; i < 10; i++) {
            Event event = new Event(i,i);
            blockingQueue.add(event);
        }*/
        int size = blockingQueue.size();
        for (int i = 0; i < size; i++) {
            Event first = blockingQueue.poll();
            System.out.println(first.getPriority());
        }
    }


}
